#include <signal.h>
#include <iostream>
#include <string>
#include <vector>

#include <workflow/WFFacilities.h>
#include <workflow/WFTaskFactory.h>
#include <workflow/RedisMessage.h>

using std::cout;
using std::endl;
using std::string;
using std::vector;

static WFFacilities::WaitGroup waitGroup(1);

void sighandler(int num)
{
    cout << "sighandler is processing" << endl;
    waitGroup.done();
}

void seriesCallback(const SeriesWork * series)
{
    cout << "seriesCallback is running" << endl;
    int * pNumber = static_cast<int*>(series->get_context());
    delete pNumber;
    pNumber = nullptr;
}


void redisCallback(WFRedisTask * redisTask)
{
    cout << "redisCallback is running" << endl;


    //错误检测
    auto req = redisTask->get_req();
    auto resp = redisTask->get_resp();
    int state = redisTask->get_state();
    int error = redisTask->get_error();
    protocol::RedisValue result;//结果集
    switch(state){
    case  WFT_STATE_SYS_ERROR:
        printf("system error: %s\n", strerror(error));break;
    case  WFT_STATE_DNS_ERROR:
        printf("dns error: %s", gai_strerror(state)); break;
    case WFT_STATE_SUCCESS:
        resp->get_result(result);
        break;
    }
    if(state != WFT_STATE_SUCCESS) {
        printf("occurs error\n");
        return;
    }

    //接下来就是解析RedisRequest
    string command;
    vector<string> params;
    req->get_command(command);
    req->get_params(params);
    cout << "Request command：" << command << " ";
    for(auto & elem : params) {
        cout << elem << " ";
    }
    cout << endl;


    //解析响应信息RedisResponse.RedisValue
    if(result.is_int()) {
        cout << "Response is int:" << result.int_value() << endl << endl;
        //在任务的回调函数中设置共享数据
        int * pNumber = new int(10);
        cout << "task *pNumber:" << *pNumber << endl;
        series_of(redisTask)->set_context(pNumber);
        //设置序列的回调函数
        series_of(redisTask)->set_callback(seriesCallback);

        //在这里创建第二个任务
        string url("redis://127.0.0.1:6379");
        auto redisTask2 = WFTaskFactory::create_redis_task(url, 0, redisCallback);

        string command("hgetall");
        vector<string> params{"student"};
        redisTask2->get_req()->set_request(command, params);
        //通过第一个任务来获取序列, 在其中添加第二个任务
        series_of(redisTask)->push_back(redisTask2);
    } else if(result.is_array()) {
        cout << "Response is array" << endl;
        for(size_t i = 0; i < result.arr_size(); ++i) {
            cout << "arr[" << i << "]:" 
                 << result.arr_at(i).string_value() << endl;
        }

        //第二个任务执行的地方
        int * pNumber = static_cast<int*>(series_of(redisTask)->get_context());
        cout << ">> *pNumber:" << *pNumber << endl;
    }
}

void test0()
{
    signal(SIGINT, sighandler);


    //1. 创建任务
    auto redisTask = WFTaskFactory::create_redis_task(
                        "redis://127.0.0.1:6379", 0, redisCallback);

    //2. 设置任务的属性
    auto req = redisTask->get_req();
    string command("hset");
    vector<string> params{"student", "name", "liubei", "age", "40"};
    req->set_request(command, params);

    //3. 交给框架调度执行
    redisTask->start();

    //4. 通过序列的context设置共享数据
    //不推荐，因为有可能在设置共享数据的过程中，
    //序列已经执行完毕了。应该在任务执行的过程中进行
    //int * pnumber = new int(10);
    //series_of(redisTask)->set_context(pnumber);

    waitGroup.wait();
}


int main()
{
    test0();
    return 0;
}

